#!/usr/bin/perl -w

#--------------------------------------------------------
# Author:  Marelie Davel (marelie.davel@gmail.com)
#--------------------------------------------------------

use strict;
use warnings;

#--------------------------------------------------------

sub print_usage() {
  print "Remaps the graphemes of a dictionary-related data file.\n";
  print "Usage: map_diacritic.pl <format> to-num|to-char <in.data> <in.map> <out.result>\n";
  print "       <format> either semicolon, htk, dictmaker, opt-patts or rules\n";
  print "       to-num: from special chars to numbers or other 1-char that is not in the language orthography\n";
  print "       to-char: from number format to special characters\n";
  print "       <in.map> in format <special-character><tab><1-character>\n";
}

#--------------------------------------------------------

sub do_map($$$$$) {
  my ($format,$type,$inDict,$inMap,$outDict) = @_;
  my ($inDH,$inMH,$outH);
  print "--Remapping dictionary--\n";
  print "Input dictionary: $inDict\n";
  print "Mapping: $inMap\n";
  print "Output dictionary: $outDict\n";
  print "Type: $type\n";
  open $inDH, '<:encoding(utf8)', $inDict or die "Cannot open $inDict";
  open $inMH, '<:encoding(utf8)', $inMap or die "Cannot open $inMap";
  open $outH, '>:encoding(utf8)', $outDict or die "Cannot open $outDict";

  my %mlist=();
  while (<$inMH>) {
    chomp;
    my @map = split /\t/,$_;
    if (@map !=2) {
      die "Error in map file: @map\n";
    }
    if ($type eq "to-num") {
      $mlist{$map[0]}=$map[1];  
    } elsif ($type eq "to-char") {
      $mlist{$map[1]}=$map[0];  
    }
  }
  close $inMH;

  my $replaced=0;
  my @letters=();
	
  if ($format eq "opt-patts") {
    while (<$inDH>) {
      chomp;
      my @line = split /;/,$_;
      if (@line !=2) {
        die "Error: line format $_\n";
      } 
      my ($sym,$pat) = @line;
      printf $outH "%s;",$sym;
      @letters = split //,$pat;
      foreach my $g (@letters) {
        if (exists $mlist{$g}) {
         print $outH "$mlist{$g}";
         $replaced++;
         print "INFO: replaced $g with $mlist{$g}\n";
        } else {
      	  print $outH "$g";
        }
      } 
      print $outH "\n";
    }
  } elsif ($format eq "rules") {
    while (<$inDH>) {
      chomp;
      my @line = split /;/,$_;
      if (@line !=6) {
        die "Error: line format $_\n";
      } 
      my $left = "$line[0];$line[1];$line[2]";
      my $right = "$line[3];$line[4];$line[5]";
      @letters = split //,$left;
      foreach my $g (@letters) {
        if (exists $mlist{$g}) {
         print $outH "$mlist{$g}";
         $replaced++;
         print "INFO: replaced $g with $mlist{$g}\n";
        } else {
      	  print $outH "$g";
        }
      } 
      print $outH ";$right\n";
    }
  } else {
    while (<$inDH>) {
      chomp;
      my @line;
      if ($format eq "semicolon") {
        @line = split /;/,$_;
      } else {
        @line = split /\t/,$_;
      }
      my $word = shift @line;
      @letters = split //,$word;
      foreach my $g (@letters) {
        if (exists $mlist{$g}) {
          print $outH "$mlist{$g}";
	  $replaced++;
        } else {
      	  print $outH "$g";
        }
      }
      if ($format eq "semicolon") {
        printf $outH ";%s\n",join ";",@line;
      } else {
        printf $outH "\t%s\n",join "\t",@line;
      }
    }
  }
  close $inDH;
  close $outH;
  print "Replaced $replaced characters\n";
}

#--------------------------------------------------------

if (scalar @ARGV<1) {
  print_usage();
  exit;
} elsif (@ARGV==5) {
  if (! (($ARGV[0] eq "semicolon")||($ARGV[0] eq "htk")||($ARGV[0] eq "dictmaker")||($ARGV[0] eq "opt-patts")||($ARGV[0] eq "rules")) ) {
    die "Only formats allowed: semicolon, htk, dictmaker, opt-patts or rules\n";
  } 
  if (! (($ARGV[1] eq "to-num")||($ARGV[1] eq "to-char")) ) {
    die "Only conversions allowed: to-num or to-char\n";
  } 
  do_map($ARGV[0],$ARGV[1],$ARGV[2],$ARGV[3],$ARGV[4]);
} else {
  print_usage();
}

#--------------------------------------------------------
